﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using Microsoft.Practices.Unity;
using Microsoft.Surface;
using Microsoft.Surface.Presentation.Controls;
using Microsoft.Win32;
using ScrumTable.Common.Collections;
using ScrumTable.Config.ConfigManagement;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.Config.ElementManagement;
using ScrumTable.Config.UserManagement;
using ScrumTable.Common.Monitoring;
using ScrumTable.UI.View.Converter;
using ScrumTable.UI.View.CustomControl;
using ScrumTable.UI.View.Util;
using ScrumTable.UI.View.WinTouch.UserControls;
using ScrumTable.UI.View.WinTouch.UserControls.Manager;
using ScrumTable.UI.View.WinTouch.UserControls.Menu;
using ScrumTable.UI.View.WinTouch.UserControls.Tool;
using ScrumTable.UI.View.WinTouch.UserControls.Tool.Toast;
using ScrumTable.UI.View.WinTouch.UserControls.View;
using ScrumTable.UI.View.WinTouch.Util;
using ScrumTable.UI.ViewModel;
using ScrumTable.UI.ViewModel.Controller;
using ScrumTable.UI.ViewModel.Data;
using ScrumTable.UI.ViewModel.Logging;
using ScrumTable.UI.ViewModel.Tools.Toast;
using Application = System.Windows.Application;
using Binding = System.Windows.Data.Binding;
using Control = System.Windows.Controls.Control;
using HorizontalAlignment = System.Windows.HorizontalAlignment;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using Label = System.Windows.Controls.Label;
using RichTextBox = System.Windows.Controls.RichTextBox;
using Size = System.Windows.Size;
using TextBox = System.Windows.Controls.TextBox;
using Microsoft.Surface.Presentation.Input;

namespace ScrumTable.UI.View.WinTouch
{
    /// <summary>
    /// AppScreen contains all functionality for creating the window view. 
    /// Contains 3 layers:
    /// 1: Window View
    /// 2: Item Window
    /// 3: Tool Window 
    /// </summary>
    public partial class AppScreen :  IRunTaskWithGuiSupplie, IAppScreen
    {

        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------
        private IUnityContainer _container;
        private bool _isDisabled;
        private ConfigManager _configManager;

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets or sets the container.
        /// </summary>
        /// <value>The container.</value>
        public IUnityContainer Container
        {
            get
            {
                return _container;
            }
            set
            {
                _container = value;
            }
        }

        /// <summary>
        /// Sets the navi controller.
        /// </summary>
        /// <value>The navi controller.</value>
        [Dependency]
        public ScrumController NaviController
        {
            set
            {
                value.ChangedView += OnChangedView;
                value.LoggedOut += OnLoggedOut;
                value.DataLogOut += OnLoggedOut;
                value.LoggedIn += OnLoggedIn;
                value.GoTo(NavigationTarget.StartView);
            }
        }


        /// <summary>
        /// Contains the Control for showing Toasts
        /// </summary>
        public ToastPublisherControl ToastControl { get; set; }


        /// <summary>
        /// ScrumData
        /// </summary>
        [Dependency]
        public ScrumViewModelData ScrumData { get; set; }


        /// <summary>
        /// ScrumData
        /// </summary>
        [Dependency]
        public ElementManager ElementManager { get; set; }

        /// <summary>
        /// ConfigManager
        /// </summary>
        [Dependency]
        public ConfigManager ConfigManager
        {
            get { return _configManager; }
            set
            {
                value.ChangedScreenSettings += OnScreenSettingChanged;
                _configManager = value;
                CreateScreenGrids(true);
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the main window is rotated (180 degree).
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is rotatet; otherwise, <c>false</c>.
        /// </value>
        public bool IsRotated { get; private set; }

        #endregion


        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------


        /// <summary>
        /// Default constructor.
        /// </summary>
        public AppScreen(IUnityContainer container)
        {
            Container = container;
            InitializeComponent();
            Width = Screen.PrimaryScreen.WorkingArea.Width;
            Height = Screen.PrimaryScreen.WorkingArea.Height;
            Top = 0;
            Left = 0;
            
            DataContext = this;
            SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged;
            new DropManager(this);
            Icon = Application.Current.Resources["ExeLogo"] as BitmapImage;
            Loaded += OnLoaded;
        }

        


        #endregion

   


        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------
        
        /// <summary>
        /// Returns the injection-container
        /// Need for Controls which are not created from the container
        /// </summary>
        /// <returns></returns>
        public IUnityContainer GetUnityContainer()
        {
            return Container;
        }
        
        /// <summary>
        /// Adds an UserControl to the front toolwindow
        /// Adds a click event for removing this window from the toolwindow
        /// Adds a resize event
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="maxize"></param>
        public bool AddItem(Control obj, bool maxize)
        {
            if (!ScatteredItemGrid.Children.Contains(obj))
            {
                if (maxize)
                {
                    obj.Width = FrontGrid.Width;
                    obj.Height = FrontGrid.Height;
                    obj.HorizontalAlignment = HorizontalAlignment.Left;
                    obj.VerticalAlignment = VerticalAlignment.Top;
                }
                FrontGrid.Children.Add(obj);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Removes the item.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <returns></returns>
        public bool RemoveItem(UIElement obj)
        {
            if (FrontGrid.Children.Contains(obj))
            {
                FrontGrid.Children.Remove(obj);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Removes the scattert item.
        /// </summary>
        /// <param name="item">The item.</param>
        public void RemoveScattertItem(ScatterViewItem item)
        {
            var obj = ViewElementUtils.FindVisualChild<ScrumUserControl>(item);
            if (obj != null)
            {
                obj.Dispose();
            }
            ItemView.Items.Remove(item);

        }


        private void RemoveAllDataItems()
        {
            FocusManager.SetFocusedElement(this, this);   //fire the onfocus event on the current selected item -> store the item befor closing

            for (int index = ItemView.Items.Count - 1; index >= 0; index--)
            {
                ScatterViewItem x = ItemView.Items[index] as ScatterViewItem;
                RemoveScattertItem(x);
            }
            ItemView.Items.Clear();

            for (int index = FrontGrid.Children.Count - 1; index >= 0; index--)
            {
                UIElement x = FrontGrid.Children[index];
                if( x is IDisposable)
                {
                    ((IDisposable)x).Dispose();
                }
                RemoveItem(x);
            }
            FrontGrid.Children.Clear();
        }


        /// <summary>
        /// Adds an image to the scatter view. 
        /// </summary>
        /// <param name="imageToShow">The image to show.</param>
        public void AddImageScatterItem(System.Drawing.Image imageToShow)
        {
            if (imageToShow == null)
            {
                return;
            }
            var converter = new ConverterBitMapToImageSource();
            var control = new ScrumUserControl
                              {
                                  Content = new Image
                                  {
                                      Source = (ImageSource)converter.Convert(imageToShow, typeof(ImageSource), null, null)
                                  }
                              };


            Point center = new Point(Width / 2.0, Height / 2.0);
            control.Width = imageToShow.Width;
            control.Height = imageToShow.Height;
            AddScatteredItem(control, center, false);
        }


        /// <summary>
        /// Adds an image to the center  of the scatter view. 
        /// </summary>
        /// <param name="uriToShow">The image to show.</param>
        /// <param name="postInformation">post information for the url.</param>
        public void AddReportImageToScatterItem(Uri uriToShow, string postInformation)
        {
            AddReportImageToScatterItem(uriToShow, postInformation, PointToScreen(new Point(Width / 2.0, Height / 2.0)));
        }
        /// <summary>
        /// Adds an image to the scatter view. 
        /// </summary>
        /// <param name="uriToShow">The image to show.</param>
        /// <param name="postInformation">post information for the url.</param>
        /// <param name="center">where this image is shown.</param>
        public void AddReportImageToScatterItem(Uri uriToShow, string postInformation, Point center)
        {
            if (uriToShow == null)
            {
                return;
            }

            var control = new ScrumUserControl
                              {
                Content = new WebAsyncImage {ClipWhiteBorderRightBottom = true, WebPostWebPair =  new Pair<Uri, string>(uriToShow,postInformation)}
            };

            control.Width = (control.Width == 0) ? control.Width : 800;
            control.Height = (control.Height == 0) ? control.Height : 600;
            AddScatteredItem(control, center, false);
        }


        /// <summary>
        /// Adds an image to the scatter view. 
        /// </summary>
        /// <param name="uriToShow">The image to show.</param>
        public void AddUriImageToScatterItem(Uri uriToShow)
        {
            if (uriToShow == null)
            {
                return;
            }

            var control = new ScrumUserControl
            {
                Content = new WebAsyncImage { UriBitmap = uriToShow }
            };

            Point center = new Point(Width / 2.0, Height / 2.0);
            control.Width = (control.Width == 0) ? control.Width : 800;
            control.Height = (control.Height == 0) ? control.Height : 600;

            AddScatteredItem(control, PointToScreen(center), false);
        }

        public void ShowToolTip(ScatterViewItem element, Control control, string toolTipText)
        {

            var toolTip = new Label
                              {
                                  Content = toolTipText,
                                  FontSize = 15,
                                  LayoutTransform = new RotateTransform(element.Orientation + 90),
                                  Effect = new DropShadowEffect()
                              };




            double c = control.ActualHeight;
            double a = Math.Cos(element.Orientation / 180 * Math.PI) * c;
            double b = Math.Sin(element.Orientation / 180 * Math.PI) * c;

            Point position = control.TransformToAncestor(Application.Current.MainWindow).Transform(new Point(0, 0));

            double left = position.X - b;
            double top = position.Y + a;


            toolTip.VerticalAlignment = VerticalAlignment.Top;
            toolTip.HorizontalAlignment = HorizontalAlignment.Left;
            toolTip.Margin = new Thickness(left, top, 0, 0);

            element.ManipulationDelta += (o, args) => RemoveItem(toolTip);
            AddItem(toolTip, false);
        }


        /// <summary>
        /// Adds an UserControl to the front toolwindow
        /// Adds a click event for removing this window from the toolwindow
        /// Adds a resize event
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="center"></param>
        /// <param name="border">Adds an border to the item</param>
        public void AddScatteredItem(ScrumUserControl obj, Point center, bool border)
        {
            AddScatteredItem(obj, center, border, true, null, false);
        }


        /// <summary>
        /// Adds an UserControl to the front toolwindow
        /// Adds a click event for removing this window from the toolwindow
        /// Adds a resize event
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <param name="center">The center.</param>
        /// <param name="border">Adds an border to the item</param>
        /// <param name="canScale">if set to <c>true</c> then the item can be scaled in size.</param>
        /// <param name="title">titel text, placed on the middle of the border.</param>
        /// <param name="isSingleItem">if true only one type of this window is placed as ScatteredItem.</param>
        /// <param name="centerOnMousePoint">if true, the item will open under the given point, otherwise it will get center on it</param>
        /// <param name="boderBrush">Color of the border</param>
        /// <param name="bottomText">border bottom text</param>
        public ScatterViewItem AddScatteredItem(ScrumUserControl obj, Point center, bool border, bool canScale, string title, bool isSingleItem, bool centerOnMousePoint = false, Binding boderBrush = null, string bottomText= null)
        {
            NavigationLogger.InfoFormat(Properties.Resources.LogAppScreenOpenScatteredItem, obj);
            return (new ScatteredViewOpener(obj, center, border, canScale, title, isSingleItem, ItemView, this, centerOnMousePoint, boderBrush,bottomText)).Item;
        }

        /// <summary>
        /// Rotates this window (180 degree)
        /// </summary>
        public void Rotate()
        {
            int angle = 180;
            if (ScatteredItemGrid.RenderTransform is RotateTransform)
            {
                angle = ((RotateTransform)ScatteredItemGrid.RenderTransform).Angle == 0 ? 180 : 0;
            }
            ToolGrid.RenderTransform = new RotateTransform(angle, ActualWidth / 2.0, ActualHeight / 2.0);
            BackGrid.RenderTransform = new RotateTransform(angle, ActualWidth / 2.0, ActualHeight / 2.0);
            ScatteredItemGrid.RenderTransform = new RotateTransform(angle, ActualWidth / 2.0, ActualHeight / 2.0);
            FrontGrid.RenderTransform = new RotateTransform(angle, ActualWidth / 2.0, ActualHeight / 2.0);
            IsRotated = IsRotated ? false : true;

        }


        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = Container.Resolve<ScrumController>().CurrentTarget != NavigationTarget.StartView;
            if (e.Cancel)
            {
                Container.Resolve<ScrumViewModelData>().Disconnect();
            }
            base.OnClosing(e);
        }


        /// <summary>
        /// Runs a action with an loading bar
        /// </summary>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        public IDisposable RunTaskLoadingBar(Action<IDisposable, IDataImportMonitor> action)
        {
            return new RunTaskWithLoadingBar(this, action);
        }

        public void RunSave(Action<SaveState> action)
        {
            if (_isDisabled) return;

            DisableGui(false);
            var saveScreen = new SaveScreen(
                Container.Resolve<ScrumViewModelData>(),
                (screen, result) =>
                {
                    ToolGrid.Children.Remove(
                        screen);
                    EnableGui();
                    action.Invoke(result);
                });

            ToolGrid.Children.Add(saveScreen);

        }

        public void ChangeUser(Action<SaveState> action, Member changeTo)
        {
            if (_isDisabled) return;

            DisableGui(false);
            var saveScreen = new SaveScreen(
                Container.Resolve<ScrumViewModelData>(),
                (screen, result) =>
                {
                    ToolGrid.Children.Remove(
                        screen);
                    EnableGui();
                    action.Invoke(result);
                }, changeTo);

            ToolGrid.Children.Add(saveScreen);

        }

        private void DisableGui(bool all)
        {
            _isDisabled = true;
            Brush brush = Brushes.LightBlue.Clone();
            brush.Opacity = 0.5;
            ToolGrid.Background = brush;
            if (all)
            {
                IsEnabled = true;
                PleaseWait.Visibility = Visibility.Visible;
            }
            BackGrid.IsEnabled = false;
            ScatteredItemGrid.IsEnabled = false;
            FrontGrid.IsEnabled = false;

        }

        private void EnableGui()
        {
            _isDisabled = false;
            PleaseWait.Visibility = Visibility.Hidden;
            ToolGrid.Background = null;
            IsEnabled = true;
            BackGrid.IsEnabled = true;
            ScatteredItemGrid.IsEnabled = true;
            FrontGrid.IsEnabled = true;
        }

        #region Screen

        /// <summary>
        /// Gets the screengrid for a given point (if exist)
        /// </summary>
        /// <param name="center"></param>
        /// <returns></returns>
        public ScreenGrid GetScreenGridForPoint(Point center)
        {
            foreach( ScreenGrid screenGrid in BackMultiMonitorGrid.Children)
            {
                if( new Rect(screenGrid.ScreenOffSet,new Size(screenGrid.Width, screenGrid.Height)).Contains(center))
                {
                    return screenGrid;
                }
            }
            return null;
        }

        private void CreateScreenGrids(bool onlyArrangeGrid=false)
        {
            Point leftTopCorner = new Point(double.MaxValue, double.MaxValue);
            Point rightBottomCorner = new Point(double.MinValue, double.MinValue);
            Screen[] screens = AllScreens();
            GetScreenMaxAndMinCorner(ref leftTopCorner, ref rightBottomCorner, screens);
            ArrangeGridToMainScreen(leftTopCorner, BackGrid);
            ArrangeGridToMainScreen(leftTopCorner, ToolGrid);
            ArrangeGridToMainScreen(leftTopCorner, FrontGrid);
            ArangeToAllScreens(leftTopCorner, rightBottomCorner, ScatteredItemGrid);
            
            
            Top = leftTopCorner.Y;
            Left = leftTopCorner.X;
            Width = rightBottomCorner.X - leftTopCorner.X;
            Height = rightBottomCorner.Y - leftTopCorner.Y;

            DestroyScreenGrids();
            if(onlyArrangeGrid) { return; }

            if (screens.Length == 1) { return; }
            foreach (Screen screen in screens)
            {
                ScreenConfig multiScreenConfig = ConfigManager.GetMultiScreenSettings(screen.DeviceName);
                ScreenGrid grid = BackMultiMonitorGrid.Children.Cast<ScreenGrid>().FirstOrDefault(o => o.MultipleScreen.Contains(screen.DeviceName));
                Type gridType;
                string args = null;
                //Check if this Screen has already a grid 
                if (multiScreenConfig != null && grid != null)
                {
                    continue;
                }

                Point leftTopCornerScreen = new Point(double.MaxValue, double.MaxValue);
                Point rightBottomCornerScreen = new Point(double.MinValue, double.MinValue);

                Screen[] screensTmp;
                if (multiScreenConfig != null)
                {
                    screensTmp = (from tmpScreen in Screen.AllScreens
                                  from screenSetting in multiScreenConfig.ScreenNames
                                  where screenSetting == tmpScreen.DeviceName
                                  select tmpScreen).ToArray();
                    gridType = multiScreenConfig.StartControlAsType;
                }
                else
                {
                    screensTmp = new[] { screen };
                    ScreenConfig config = ConfigManager.GetScreenSettings(screen.DeviceName);
                    gridType = config == null ? null : config.StartControlAsType;
                    args = config == null ? null : config.Args;
                }
                GetScreenMaxAndMinCorner(ref leftTopCornerScreen, ref rightBottomCornerScreen, screensTmp);


                grid = new ScreenGrid { ScreenOffSet = new Point(leftTopCornerScreen.X - leftTopCorner.X, leftTopCornerScreen.Y - leftTopCorner.Y), Screen = screen.DeviceName, MultipleScreen = screensTmp.Aggregate(string.Empty, (current, na) => current + ";" + na.DeviceName)};
                Container.BuildUp(grid);
                BackMultiMonitorGrid.Children.Add(grid);

                grid.Width = rightBottomCornerScreen.X - leftTopCornerScreen.X;
                grid.Height = rightBottomCornerScreen.Y - leftTopCornerScreen.Y;
                grid.Margin = new Thickness(grid.ScreenOffSet.X, grid.ScreenOffSet.Y, 0, 0);
                grid.VerticalAlignment = VerticalAlignment.Top;
                grid.HorizontalAlignment = HorizontalAlignment.Left;
                grid.SetControl(gridType, args);

            }
        }

        private Screen[] AllScreens()
        {
            if(!ConfigManager.Config.MultiScreenModeEnabled)
            {
                return new []{Screen.PrimaryScreen};    
            }
            return Screen.AllScreens;
        }

        private static void ArrangeGridToMainScreen(Point leftTopCorner, Grid grid)
        {
            grid.Margin = new Thickness(-leftTopCorner.X, -leftTopCorner.Y, 0, 0);
            grid.Width = Screen.PrimaryScreen.Bounds.Width;
            grid.Height = Screen.PrimaryScreen.Bounds.Height;
            grid.VerticalAlignment = VerticalAlignment.Top;
            grid.HorizontalAlignment = HorizontalAlignment.Left;
        }

        private static void ArangeToAllScreens(Point min, Point max, Grid grid)
        {
            grid.Margin = new Thickness(0);
            grid.Width = max.X - min.X;
            grid.Height = max.Y - min.Y;
            grid.VerticalAlignment = VerticalAlignment.Top;
            grid.HorizontalAlignment = HorizontalAlignment.Left;
        }

        internal static void GetScreenMaxAndMinCorner(ref Point min, ref Point max, IEnumerable<Screen> screens)
        {

            min = new Point(double.MaxValue, double.MaxValue);
            max = new Point(double.MinValue, double.MinValue);
            foreach (var screen in screens)
            {
                min.X = Math.Min(min.X, screen.Bounds.X);
                min.Y = Math.Min(min.Y, screen.Bounds.Y);

                max.X = Math.Max(max.X, screen.Bounds.X + screen.Bounds.Width);
                max.Y = Math.Max(max.Y, screen.Bounds.Y + screen.Bounds.Height);

            }
        }


        private void DestroyScreenGrids()
        {
            foreach (ScreenGrid x in BackMultiMonitorGrid.Children)
            {
                x.Dispose();
            }
            BackMultiMonitorGrid.Children.Clear();
        }
        #endregion

        private void ChangeView(NavigationEventArgs e)
        {
            //Check if target is in current tab
            if (BackGrid.Children.Count == 0 || !ShowTargetInCurrentSplitControl(e))
            {
                if (BackGrid.Children.Count > 0)
                {
                    ((ScrumUserControl)BackGrid.Children[0]).Dispose();

                }
                BackGrid.Children.Clear();
                BackGrid.Children.Add(GetViewControl(e.Target));
                ShowTargetInCurrentSplitControl(e);
            }
            if (e.Target != NavigationTarget.StartView)
            {
                Container.Resolve<LoginAccountManager>().CurrentLoginAccount.LastUsedScreen = e.Target.ToString();
            }
        }

        private bool ShowTargetInCurrentSplitControl(NavigationEventArgs e)
        {
            if (BackGrid.Children[0] is SplitControl && ((SplitControl) BackGrid.Children[0]).IsTargetInContext(e.Target))
            {
                SplitControl splitControl = (SplitControl) BackGrid.Children[0];
                splitControl.OpenTarget(e.Target);
                return true;
            }
            return false;
        }


        private ScrumUserControl GetViewControl(NavigationTarget target)
        {
            NavigationLogger.InfoFormat(Properties.Resources.LogStartScrViewChange, target);
            //Entries without a menu
            if( target == NavigationTarget.StartView)
            {
                RemoveAllDataItems();
                return Container.Resolve<StartScreenControl>();
            }

            Dictionary<NavigationTarget, ScrumUserControl> list = new Dictionary<NavigationTarget, ScrumUserControl>();
            var menu = Container.Resolve<RingMenu>();
            var meetingEntry = menu.GetMeetingEntry(target);
            if (meetingEntry != null)
            {
                if (meetingEntry.Children.Count == 0)
                {
                    list.Add(meetingEntry.NavigatonTarget, GetControlForTarget(meetingEntry.NavigatonTarget));
                }
                else
                {
                    foreach (var entry in meetingEntry.Children)
                    {
                        if (entry.NavigatonTarget != NavigationTarget.Null)
                        {
                            list.Add(entry.NavigatonTarget, GetControlForTarget(entry.NavigatonTarget));
                        }
                    }
                }
                return new SplitControl(menu, list);
            }
            //Go ScrumMap if something failes
            list.Add(NavigationTarget.ScrumMap, GetScrumMapControl());
            return new SplitControl(menu, list);
        }

        private ScrumUserControl GetControlForTarget(NavigationTarget  target)
        {
            switch (target)
            {
                case NavigationTarget.RegisterViewNoWizard:
                case NavigationTarget.RegisterView:
                    {
                        return Container.Resolve<Register>();
                    }
                case NavigationTarget.SettingConfigNoWizard:
                case NavigationTarget.SettingConfig:
                    {
                        return Container.Resolve<ConfigSetting>();
                    }
                case NavigationTarget.TeamMemberSettingsNoWizard:
                case NavigationTarget.TeamMemberSettings:
                    {
                        return Container.Resolve<MemberSetting>();
                    }
                case NavigationTarget.ProjectConfigNoWizard:
                case NavigationTarget.ProjectConfig:
                    {
                        return Container.Resolve<ProjectSetting>();
                    }
                case NavigationTarget.ScrumMap:
                    {
                        return GetScrumMapControl();
                    }
                case NavigationTarget.ProjectPlanningUserStories:
                    {
                        return Container.Resolve<ProjectPlanningUserStories>();
                    }
                case NavigationTarget.ProjectPlanningScrumPoker:
                    {
                        return Container.Resolve<ProjectPlanningScrumPoker>();
                    }
                case NavigationTarget.ProjectPlanningIterations:
                    {
                        return Container.Resolve<ProjectPlanningIterations>();
                    }
                case NavigationTarget.SprintPlanningTask:
                    {
                        return Container.Resolve<SprintPlanningTask>();
                    }
                case NavigationTarget.DailyScrumIndividualReport:
                    {
                        var dailyScrumIndividualReport = Container.Resolve<DailyScrumIndividualReport>();
                        dailyScrumIndividualReport.Config = ElementManager.GetTargetConfig(NavigationTarget.DailyScrumIndividualReport.ToString());
                        return dailyScrumIndividualReport;
                    }
                case NavigationTarget.DailyScrumBoard:
                    {
                        var stackedboard = Container.Resolve<StackedDailyScrumStoryBoard>();
                        stackedboard.Config = ElementManager.GetTargetConfig(NavigationTarget.DailyScrumBoard.ToString());
                        return stackedboard;
                    }
                case NavigationTarget.DailyScrumStoryBoard:
                    {
                        var board = Container.Resolve<DynamicBoard>();
                        board.Config = ElementManager.GetTargetConfig(NavigationTarget.DailyScrumStoryBoard.ToString());
                        return board;
                    }
                case NavigationTarget.DailyScrumTaskBoard:
                    {
                        var board = Container.Resolve<DynamicBoard>();
                        board.Config = ElementManager.GetTargetConfig(NavigationTarget.DailyScrumTaskBoard.ToString());
                        return board;
                    }
                default:
                    return null;
            }
        }
       
        private ScrumUserControl GetScrumMapControl()
        {
            //mg custom map is currently removed
            if (_container.Resolve<ConfigManager>().Config.ShowCustomScrumMap)
            {
                return Container.Resolve<ScrumMap>();
            }
            else
            {
                return Container.Resolve<ScrumMap>();
            }
        }
        
        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (SurfaceUtil.IsSurfaceRunning())
            {
                HwndSource hwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
                IntPtr hwnd = hwndSource != null ? hwndSource.Handle : IntPtr.Zero;
                SurfaceKeyboard.SuppressTextInputPanel(hwnd);
                this.EnableSurfaceInput();
            }
            ApplicationServices.SignalApplicationLoadComplete();
            Loaded -= OnLoaded;
        }

        private void OnScreenSettingChanged(object sender, EventArgs e)
        {
            CreateScreenGrids();
        }

        private void OnLoggedOut(object sender, EventArgs e)
        {
            Container.Resolve<ViewModelToastScreen>().RemovePublisher(ToastType.Error);
            RemoveAllDataItems();
            DestroyScreenGrids();
        }


        private void OnLoggedIn(object sender, EventArgs e)
        {
            CreateScreenGrids();
            Container.Resolve<ViewModelToastScreen>().AddErrorPublisher();
            /* currenty disabled, because of a wish of a current person. This lines adds the member change control after the login process
            if (ScrumData.IsMultipleLogin)
            {
                var x = _container.Resolve<MemberChangeControl>();
                AddScatteredItem(x, BackGrid.PointToScreen( new Point(BackGrid.ActualWidth / 2, BackGrid.ActualHeight - 35)), false, false, null, true);
            }*/
            MemberViewModel.SetInitColors(Container.Resolve<LoginAccountManager>().CurrentLoginAccount.MemberColors);
             
        }

        /// <summary>
        /// Occurs when the window is about to close. 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosed(EventArgs e)
        {
            SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged;
            base.OnClosed(e);
        }


        private void OnDisplaySettingsChanged(object sender, EventArgs e)
        {
            CreateScreenGrids();
        }

        private void OnPreviewKeyDown(object sender, KeyEventArgs e)
        {
            var uie = e.OriginalSource as UIElement;
            if (e.Key == Key.Enter && !(uie is TextBox && ((TextBox)(uie)).AcceptsReturn) && !(uie is RichTextBox))
            {
                if (uie != null)
                {
                    e.Handled = true;
                    uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                }
            }
        }

        private void OnChangedView(object sender, NavigationEventArgs e)
        {
            ChangeView(e);
        }


        private void OnToolButtonClick(object sender, RoutedEventArgs e)
        {
            var x = Container.Resolve<ToolBox>();
            AddScatteredItem(x, PointToScreen(new Point(Width / 2, Height - 50)), false, false, null, true);
        }

  
        #endregion
        #region  RunTaskWithLoadingBar
        private class RunTaskWithLoadingBar : IDisposable, IDataImportMonitor
        {
            private readonly AppScreen _parent;
            #region IDisposable Members

            internal RunTaskWithLoadingBar(AppScreen parent, Action<IDisposable, IDataImportMonitor> action)
            {

                _parent = parent;
                _parent.DisableGui(true);
                action(this, this);


            }

            void IDisposable.Dispose()
            {
                _parent.EnableGui();
            }

            #endregion

            public void StartSubProgress(string identifier)
            {
                _parent.PleaseWait.StartSubProgress(identifier);
            }

            public void ReportProgress(string identifier, byte current)
            {
                _parent.PleaseWait.ReportProgress(identifier, current);
            }

            public void ReportProgress(string identifier, int current, int max)
            {
            }

            public void EndSubProgress(string identifier, Exception e)
            {
                _parent.PleaseWait.EndSubProgress(identifier, e);
                if (_parent.PleaseWait.ItemsToLoad.Count == 0 || e != null)
                {
                    ((IDisposable)(this)).Dispose();
                }
            }
        }



        #endregion
        
    } 
}


